home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / pine / args.c < prev    next >
C/C++ Source or Header  |  1996-05-31  |  14KB  |  523 lines

  1. #if !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: args.c,v 4.57 1996/05/31 22:06:42 mikes Exp $";
  3. #endif
  4. /*----------------------------------------------------------------------
  5.  
  6.             T H E    P I N E    M A I L   S Y S T E M
  7.  
  8.    Laurence Lundblade and Mike Seibel
  9.    Networks and Distributed Computing
  10.    Computing and Communications
  11.    University of Washington
  12.    Administration Builiding, AG-44
  13.    Seattle, Washington, 98195, USA
  14.    Internet: lgl@CAC.Washington.EDU
  15.              mikes@CAC.Washington.EDU
  16.  
  17.    Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  18.  
  19.  
  20.    Pine and Pico are registered trademarks of the University of Washington.
  21.    No commercial use of these trademarks may be made without prior written
  22.    permission of the University of Washington.
  23.  
  24.    Pine, Pico, and Pilot software and its included text are Copyright
  25.    1989-1996 by the University of Washington.
  26.  
  27.    The full text of our legal notices is contained in the file called
  28.    CPYRIGHT, included with this distribution.
  29.  
  30.  
  31.    Pine is in part based on The Elm Mail System:
  32.     ***********************************************************************
  33.     *  The Elm Mail System  -  Revision: 2.13                             *
  34.     *                                                                     *
  35.     *             Copyright (c) 1986, 1987 Dave Taylor              *
  36.     *             Copyright (c) 1988, 1989 USENET Community Trust   *
  37.     ***********************************************************************
  38.  
  39.  
  40.   ----------------------------------------------------------------------*/
  41.  
  42. /*======================================================================
  43.       args.c
  44.       Command line argument parsing functions 
  45.  
  46.   ====*/
  47.  
  48. #ifdef    OS2
  49. #define    INCL_DOS
  50. #define    INCL_NOPM
  51. #define INCL_VIO
  52. #include <os2.h>
  53. #undef ADDRESS
  54. #endif
  55. #include "headers.h"
  56.  
  57. void args_help PROTO(());
  58. void display_args_err PROTO((char *, char **, int));
  59.  
  60.  
  61. /*
  62.  * Name started as to invoke function key mode
  63.  */
  64. #define    PINE_FKEY_NAME    "pinef"
  65.  
  66. /*
  67.  * Various error and informational strings..
  68.  */
  69. char args_err_missing_pinerc[] =    "missing argument for option \"-pinerc\" (use - for standard out)";
  70. char args_err_missing_lu[] =        "missing argument for option \"-create_lu\"\nUsage: pine -create_lu <addrbook_file> <addrbook_sort_type>";
  71. char args_err_missing_sort[] =        "missing argument for option \"-sort\"";
  72. char args_err_missing_flag_arg[] =    "missing argument for flag \"%c\"";
  73. char args_err_missing_flag_num[] =    "Non numeric argument for flag \"%c\"";
  74. char args_err_unknown[] =        "unknown flag \"%c\"";
  75. char args_err_I_error[] =        "-I argument \"%s\": %s";
  76. char args_err_internal[] =        "%s";
  77.  
  78.  
  79. char *args_pine_args[] = {
  80. "Possible Starting Arguments for Pine program:",
  81. "",
  82. "\tArgument\t\tMeaning",
  83. "\t <addrs>...\tGo directly into composer sending to given address",
  84. "\t\t\tStandard input redirection is allowed with addresses.",
  85. #ifdef    DEBUG
  86. "\t -d n\t\tDebug - set debug level to 'n'",
  87. #endif
  88. "\t -f <folder>\tFolder - give folder name to open",
  89. "\t -c <number>\tContext - which context to apply to -f arg",
  90. "\t -F <file>\tFile - give file name to open and page thru",
  91. "\t -h \t\tHelp - give this list of options",
  92. "\t -k \t\tKeys - Force use of function keys",
  93. "\t -z \t\tSuspend - allow use of ^Z suspension",
  94. "\t -r \t\tRestricted - can only send mail to one self",
  95. "\t -sort <sort> \tSort - Specify sort order of folder:",
  96. "\t\t\t        subject, arrival, date, from, size, /reverse",
  97. "\t -i\t\tIndex - Go directly to index, bypassing main menu",
  98. "\t -I <keystroke_list>\tInitial keystrokes to be executed",
  99. "\t -n <number>\tEntry in index to begin on",
  100. "\t -o \t\tReadOnly - Open first folder read-only",
  101. "\t -conf\t\tConfiguration - Print out fresh global configuration",
  102. "\t -pinerc <file>\tConfiguration - Put fresh pinerc configuration in <file>",
  103. "\t -p <pinerc>\tUse alternate .pinerc file",
  104. #if    !defined(DOS) && !defined(OS2)
  105. "\t -P <pine.conf>\tUse alternate pine.conf file",
  106. #endif
  107. #if defined(OS2)
  108. "\t -w <rows>\tSet window size in rows on startup",
  109. #endif
  110. "\t -create_lu <abook_file> <ab_sort_type>   create .lu from script",
  111. "\t -nr\t\tSpecial mode for UWIN",
  112. "\t -a\t\tSpecial anonymous mode for UWIN",
  113. "\t -l\t\tList - Expand List of folder collections by default",
  114. "\t -<option>=<value>\tAssign <value> to the pinerc option <option>",
  115. "\t\t\t        e.g. -signature-file=sig1",
  116. "\t\t\t        (Note: feature-list is additive)",
  117. NULL
  118. };
  119.  
  120.  
  121.  
  122. /*
  123.  *  Parse the command line args.
  124.  *
  125.  *  Args: pine_state -- The pine_state structure to put results in
  126.  *        argc, argv -- The obvious
  127.  *        addrs      -- Pointer to address list that we set for caller
  128.  *
  129.  * Result: command arguments parsed
  130.  *       possible printing of help for command line
  131.  *       various flags in pine_state set
  132.  *       returns the string name of the first folder to open
  133.  *       addrs is set
  134.  */
  135. char *
  136. pine_args(pine_state, argc, argv, addrs)
  137.      struct pine  *pine_state;
  138.      int           argc;
  139.      char        **argv;
  140.      char       ***addrs;
  141. {
  142.     register int    ac;
  143.     register char **av;
  144.     int   c;
  145.     char *str;
  146.     char *folder              = NULL;
  147.     char *cmd_list            = NULL;
  148.     char *sort                = NULL;
  149.     char *pinerc_file         = NULL;
  150.     char *addrbook_file       = NULL;
  151.     char *ab_sort_descrip     = NULL;
  152.     char *lc              = NULL;
  153.     int   do_help             = 0;
  154.     int   do_conf             = 0;
  155.     int   anonymous           = 0;
  156.     int   usage               = 0;
  157.     int   do_use_fk           = 0;
  158.     int   do_can_suspend      = 0;
  159.     int   do_expanded_folders = 0;
  160.     struct variable *vars     = pine_state->vars;
  161.  
  162.     
  163.     ac = argc;
  164.     av = argv;
  165.  
  166.     pine_state->pine_name = (lc = last_cmpnt(argv[0])) ? lc : (lc = argv[0]);
  167. #ifdef    OS2
  168.     /*
  169.      * argv0 is not reliable under OS2, so we have to get
  170.      * the executable path from the environment block
  171.      */
  172.     {
  173.       PTIB ptib;
  174.       PPIB ppib;
  175.       char * p;
  176.       DosGetInfoBlocks(&ptib, &ppib);
  177.       p = ppib->pib_pchcmd - 1;
  178.       while (*--p)
  179.     ;
  180.       ++p;
  181.       strcpy(tmp_20k_buf, p);
  182.       if ((p = strrchr(tmp_20k_buf, '\\'))!=NULL)
  183.     *++p = '\0';
  184.       pine_state->pine_dir = cpystr(tmp_20k_buf);
  185.     }
  186. #endif
  187. #ifdef    DOS
  188.     sprintf(tmp_20k_buf, "%.*s", pine_state->pine_name - argv[0], argv[0]);
  189.     pine_state->pine_dir = cpystr(tmp_20k_buf);
  190. #endif
  191.  
  192.       /* while more arguments with leading - */
  193. Loop: while(--ac > 0 && **++av == '-'){
  194.      /* while more chars in this argument */
  195.      while(*++*av){
  196.         /* check for pinerc options */
  197.         if(pinerc_cmdline_opt(*av)){
  198.            goto Loop;  /* done with this arg, go to next */
  199.         /* then other multi-char options */
  200.         }else if(strcmp(*av, "conf") == 0){
  201.            do_conf = 1;
  202.            goto Loop;  /* done with this arg, go to next */
  203.         }else if(strcmp(*av, "pinerc") == 0){
  204.            if(--ac){
  205.            pinerc_file = *++av;
  206.            }else{
  207.            display_args_err(args_err_missing_pinerc, NULL, 1);
  208.            ++usage;
  209.            }
  210.            goto Loop;
  211.         }else if(strcmp(*av, "create_lu") == 0){
  212.            if(ac > 2){
  213.               ac -= 2;
  214.           addrbook_file   = *++av;
  215.           ab_sort_descrip = *++av;
  216.            }else{
  217.            display_args_err(args_err_missing_lu, NULL, 1);
  218.            exit(-1);
  219.            }
  220.            goto Loop;
  221.         }else if(strcmp(*av, "nr") == 0){
  222.            pine_state->nr_mode = 1;
  223.            goto Loop;
  224.         }else if(strcmp(*av, "sort") == 0){
  225.            if(--ac){
  226.            sort = *++av;
  227.            COM_SORT_KEY = cpystr(sort);
  228.            }else{
  229.            display_args_err(args_err_missing_sort, NULL, 1);
  230.            ++usage;
  231.            }
  232.            goto Loop;
  233.  
  234.         /* single char flags */
  235.         }else{
  236.            switch(c = **av) {
  237.          case 'h':
  238.            do_help = 1;
  239.            break;            /* break back to inner-while */
  240.          case 'k':
  241.            do_use_fk = 1;
  242.            break;
  243.          case 'a':
  244.            anonymous = 1;
  245.            break;
  246.          case 'z':
  247.            do_can_suspend = 1;
  248.            break;
  249.          case 'r':
  250.            pine_state->restricted = 1;
  251.            break;
  252.          case 'o':
  253.            pine_state->open_readonly_on_startup = 1;
  254.            break;
  255.          case 'i':
  256.            pine_state->start_in_index = 1;
  257.            break;
  258.          case 'l':
  259.            do_expanded_folders = 1;
  260.            break;
  261.          /* these take arguments */
  262.          case 'f' : case 'F': case 'p': case 'I':
  263.          case 'c' :            /* string args */
  264. #if    !defined(DOS) && !defined(OS2)
  265.          case 'P':            /* also a string */
  266. #endif
  267.          case 'n':            /* integer args */
  268. #ifdef    OS2
  269.          case 'w':
  270. #endif
  271. #ifdef    DEBUG
  272.          case 'd':
  273. #endif
  274.            if(*++*av){
  275.               str = *av;
  276.            }else if(--ac){
  277.               str = *++av;
  278.            }else{
  279.                sprintf(tmp_20k_buf, args_err_missing_flag_arg, c);
  280.                display_args_err(tmp_20k_buf, NULL, 1);
  281.                ++usage;
  282.                goto Loop;
  283.            }
  284.            switch(c){
  285.              case 'f':
  286.                folder = str;
  287.                break;
  288.              case 'F':
  289.                folder = str;
  290.                pine_state->more_mode = 1;
  291.                break;
  292.              case 'I':
  293.                cmd_list = str;
  294.                break;
  295.              case 'p':
  296.                if(str != NULL)
  297.               pine_state->pinerc = cpystr(str);
  298.                break;
  299. #if    !defined(DOS) && !defined(OS2)
  300.              case 'P':
  301.                if(str != NULL)
  302.               pine_state->pine_conf = cpystr(str);
  303.                break;
  304. #endif
  305.              case 'd':
  306.              case 'c':
  307.                if(!isdigit((unsigned char)str[0])){
  308.                sprintf(tmp_20k_buf, args_err_missing_flag_num, c);
  309.                display_args_err(tmp_20k_buf, NULL, 1);
  310.                ++usage;
  311.                break;
  312.                }
  313.  
  314.                if(c == 'c')
  315.              pine_state->init_context = (short) atoi(str);
  316. #ifdef    DEBUG
  317.                else
  318.              debug = atoi(str);
  319. #endif
  320.  
  321.                break;
  322.  
  323.              case 'n':
  324.                if(!isdigit((unsigned char)str[0])){
  325.                sprintf(tmp_20k_buf, args_err_missing_flag_num, c);
  326.                display_args_err(tmp_20k_buf, NULL, 1);
  327.                ++usage;
  328.                break;
  329.                }
  330.  
  331.                pine_state->start_entry = atoi(str);
  332.                if (pine_state->start_entry < 1)
  333.               pine_state->start_entry = 1;
  334.                break;
  335. #ifdef    OS2
  336.              case 'w':
  337.                {
  338.                USHORT nrows = (USHORT)atoi(str);
  339.                if (nrows > 10 && nrows < 255) {
  340.                    VIOMODEINFO mi;
  341.                    mi.cb = sizeof(mi);
  342.                    if (VioGetMode(&mi, 0)==0){
  343.                    mi.row = nrows;
  344.                    VioSetMode(&mi, 0);
  345.                    }
  346.                }
  347.                }
  348. #endif
  349.            }
  350.            goto Loop;
  351.  
  352.          default:
  353.                sprintf(tmp_20k_buf, args_err_unknown, c);
  354.                display_args_err(tmp_20k_buf, NULL, 1);
  355.                ++usage;
  356.                break;
  357.            }
  358.         }
  359.      }
  360.       }
  361.  
  362.     if(cmd_list){
  363.     int    commas         = 0;
  364.     char  *p              = cmd_list;
  365.     char  *error          = NULL;
  366.  
  367.     while(*p++)
  368.         if(*p == ',')
  369.         ++commas;
  370.  
  371.     COM_INIT_CMD_LIST = parse_list(cmd_list, commas+1, &error);
  372.     if(error){
  373.         sprintf(tmp_20k_buf, args_err_I_error, cmd_list, error);
  374.         display_args_err(tmp_20k_buf, NULL, 1);
  375.         exit(-1);
  376.     }
  377.     }
  378.  
  379.     if(lc && strncmp(lc, PINE_FKEY_NAME, sizeof(PINE_FKEY_NAME) - 1) == 0)
  380.       do_use_fk = 1;
  381.  
  382.     if(do_use_fk || do_can_suspend || do_expanded_folders){
  383.     char   list[500];
  384.     int    commas         = 0;
  385.     char  *p              = list;
  386.     char  *error          = NULL;
  387.  
  388.         list[0] = '\0';
  389.  
  390.         if(do_use_fk){
  391.         if(list[0])
  392.             (void)strcat(list, ",");
  393.         (void)strcat(list, "use-function-keys");
  394.     }
  395.     if(do_can_suspend){
  396.         if(list[0])
  397.             (void)strcat(list, ",");
  398.         (void)strcat(list, "enable-suspend");
  399.     }
  400.     if(do_expanded_folders){
  401.         if(list[0])
  402.             (void)strcat(list, ",");
  403.         (void)strcat(list, "expanded-view-of-folders");
  404.     }
  405.  
  406.     while(*p++)
  407.         if(*p == ',')
  408.         ++commas;
  409.     pine_state->feat_list_back_compat = parse_list(list, commas+1, &error);
  410.     if(error){
  411.         sprintf(tmp_20k_buf, args_err_internal, error);
  412.         display_args_err(tmp_20k_buf, NULL, 1);
  413.         exit(-1);
  414.     }
  415.     }
  416.  
  417.     if(anonymous){
  418.     if(pine_state->nr_mode){
  419.         pine_state->anonymous = 1;
  420.     }
  421.     else{
  422.         display_args_err("Can't currently use -a without -nr", NULL, 1);
  423.         exit(-1);
  424.     }
  425.     }
  426.  
  427.     if(do_conf && pinerc_file){
  428.       display_args_err("Can't have both -conf and -pinerc", NULL, 1);
  429.       exit(-1);
  430.     }
  431.     if(do_conf && addrbook_file){
  432.       display_args_err("Can't have both -conf and -create_lu", NULL, 1);
  433.       exit(-1);
  434.     }
  435.     if(pinerc_file && addrbook_file){
  436.       display_args_err("Can't have both -pinerc and -create_lu", NULL, 1);
  437.       exit(-1);
  438.     }
  439.  
  440.     if(do_help || usage)
  441.       args_help(); 
  442.  
  443.     if(usage)
  444.       exit(-1);
  445.  
  446.     if(do_conf)
  447.       dump_global_conf();
  448.     if(pinerc_file)
  449.       dump_new_pinerc(pinerc_file);
  450.     if(addrbook_file)
  451.       just_update_lookup_file(addrbook_file, ab_sort_descrip);
  452.  
  453.     pine_state->show_folders_dir = 0;
  454.  
  455.     if(ac <= 0)
  456.       *av = NULL;
  457.  
  458.     *addrs = av;
  459.  
  460.     return(folder);
  461. }
  462.  
  463.  
  464. /*----------------------------------------------------------------------
  465.     print a few lines of help for command line arguments
  466.  
  467.   Args:  none
  468.  
  469.  Result: prints help messages
  470.   ----------------------------------------------------------------------*/
  471. void
  472. args_help()
  473. {
  474.     /**  print out possible starting arguments... **/
  475.     display_args_err(NULL, args_pine_args, 0);
  476.     exit(1);
  477. }
  478.  
  479.  
  480. /*----------------------------------------------------------------------
  481.    write argument error to the display...
  482.  
  483.   Args:  none
  484.  
  485.  Result: prints help messages
  486.   ----------------------------------------------------------------------*/
  487. void
  488. display_args_err(s, a, err)
  489.     char  *s;
  490.     char **a;
  491.     int    err;
  492. {
  493.     char  errstr[256], *errp;
  494.     FILE *fp = err ? stderr : stdout;
  495.  
  496.  
  497.     if(err && s)
  498.       sprintf(errp = errstr, "Argument Error: %.200s", s);
  499.     else
  500.       errp = s;
  501.  
  502. #ifdef    _WINDOWS
  503.     if(errp)
  504.       mswin_messagebox(errp, err);
  505.  
  506.     if(a && *a){
  507.     strcpy(tmp_20k_buf, *a++);
  508.     while(a && *a){
  509.         strcat(tmp_20k_buf, "\n");
  510.         strcat(tmp_20k_buf, *a++);
  511.     }
  512.  
  513.     mswin_messagebox(tmp_20k_buf, err);
  514.     }
  515. #else
  516.     if(errp)
  517.       fprintf(fp, "%s\n", errp);
  518.  
  519.     while(a && *a)
  520.       fprintf(fp, "%s\n", *a++);
  521. #endif
  522. }
  523.